package com.wigem.approve.utils;

import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wigem.approve.entity.ElementPlusTableColumnModel;
import com.wigem.approve.entity.ElementPlusTableModel;
import com.wigem.approve.entity.TableRemarkModel;
import com.wigem.approve.entity.TwoTuple;
import com.wigem.framework.excel.core.handler.ExcelHandler;
import com.wigem.util.StringUtils;
import org.apache.poi.ss.usermodel.BorderStyle;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class EcoExcelUtils {
    @Resource
    private ExcelHandler excelHandler = new ExcelHandler();

    private ElementPlusTableModel tableModel;

    private String dataString;

    //序号列标记
    public static final String SORT_CODE = "sortCode";

    //表头行数
    private int headSize = 1;
    //标题行数
    private int titleSize = 0;
    //数据行数
    private int dataSize = 0;

    public EcoExcelUtils(ElementPlusTableModel tableModel, String dataString) {
        this.tableModel = tableModel;
        this.dataString = dataString;
    }

    /**
     * 导出表格
     *
     * @param response
     * @throws IOException
     */
    public void doExport(HttpServletResponse response) throws IOException {
        //转换数据
        TwoTuple twoTuple = this.convertTableData(this.dataString);
        //获取表头
        List<List<String>> head = this.getTableHead(this.tableModel.getCols());
        //获取主体数据
        List<List<Object>> data = this.getBodyData(twoTuple);
        //获取注释
        Object[] remarks = this.getRemarks();
        //获取表格基础数据
        getExcelBaseData(head, data);
        //获取边框样式
        WriteCellStyle writeCellStyle = getBorderStyle();
        excelHandler.fileName(this.tableModel.getTableName());
        if (this.titleSize > 0) {
            String title = this.tableModel.getTitle();
            if (StringUtils.isNotEmpty(this.tableModel.getUnit())) {
                title = this.tableModel.getTitle() + "(" + this.tableModel.getUnit() + ")";
            }
            excelHandler.title(title).headStyle(writeCellStyle);
        }
        if (this.headSize > 0) {
            excelHandler.addHeads(head);
        }
        if (this.dataSize > 0) {
            excelHandler.data(data).contentStyle(writeCellStyle);
        }
        if (remarks.length > 0) {
            excelHandler.addRow(remarks)
                    .mergeCell(this.titleSize + this.headSize + this.dataSize,
                            this.titleSize + this.headSize + this.dataSize,
                            0, getHeadPropList().size() - 1);
        }
        excelHandler.registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 36, (short) 20));
        excelHandler.doExport(response);
    }

    public void downLoad(String outPath) throws Exception {
        TwoTuple twoTuple = this.convertTableData(this.dataString);
        //获取表头
        List<List<String>> head = this.getTableHead(this.tableModel.getCols());
        //获取主体数据
        List<List<Object>> data = this.getBodyData(twoTuple);
        //获取注释
        Object[] remarks = this.getRemarks();
        //获取表格基础数据
        getExcelBaseData(head, data);
        //获取边框样式
        WriteCellStyle writeCellStyle = getBorderStyle();
        excelHandler.fileName(this.tableModel.getTableName());
        if (this.titleSize > 0) {
            String title = this.tableModel.getTitle();
            if (StringUtils.isNotEmpty(this.tableModel.getUnit())) {
                title = this.tableModel.getTitle() + "(" + this.tableModel.getUnit() + ")";
            }
            excelHandler.title(title).headStyle(writeCellStyle);
        }
        if (this.headSize > 0) {
            excelHandler.addHeads(head);
        }
        if (this.dataSize > 0) {
            excelHandler.data(data).contentStyle(writeCellStyle);
            if (remarks.length > 0) {
                excelHandler.addRow(remarks)
                        .mergeCell(this.titleSize + this.headSize + this.dataSize,
                                this.titleSize + this.headSize + this.dataSize,
                                0, getHeadPropList().size() - 1);
            }
            excelHandler.registerWriteHandler(new SimpleRowHeightStyleStrategy((short) 36, (short) 20));
            excelHandler.downLoad(outPath);
        }
    }

    public static void setFillUserInfo() {

    }

    public static WriteCellStyle getBorderStyle() {
        WriteCellStyle writeCellStyle = new WriteCellStyle();
        // 左边框
        writeCellStyle.setBorderLeft(BorderStyle.THIN);
        // 上边框
        writeCellStyle.setBorderTop(BorderStyle.THIN);
        // 右边框
        writeCellStyle.setBorderRight(BorderStyle.THIN);
        // 下边框
        writeCellStyle.setBorderBottom(BorderStyle.THIN);
        return writeCellStyle;
    }

    public void getExcelBaseData(List<List<String>> head, List<List<Object>> data) {
        for (List<String> item : head) {
            if (item.size() > 1) {
                this.headSize = 2;
            }
        }
        this.dataSize = data.size();
        if (StringUtils.isNotEmpty(this.tableModel.getTitle())) {
            this.titleSize = 1;
        }
    }

    /**
     * 获取表头数据
     *
     * @return List<List < String>>
     */
    public static List<List<String>> getTableHead(List<ElementPlusTableColumnModel> cols) {
        List<List<String>> result = new ArrayList<>();
        //添加序号列
        List<String> sortCodeStr = new ArrayList<>();
        sortCodeStr.add("序号");
        result.add(sortCodeStr);
        for (ElementPlusTableColumnModel item : cols) {
            if (item != null) {
                if (item.getChildren() != null) {
                    for (ElementPlusTableColumnModel child : item.getChildren()) {
                        List<String> list1 = new ArrayList<>();
                        list1.add(item.getLabel());
                        list1.add(child.getLabel());
                        result.add(list1);
                    }
                } else {
                    List<String> list1 = new ArrayList<>();
                    list1.add(item.getLabel());
                    result.add(list1);
                }
            }
        }
        return result;
    }

    /**
     * 获取表格合计行
     *
     * @param totalRowJsonObj
     * @return List<List < Object>>
     */
    private List<Object> getTotal(JSONObject totalRowJsonObj) {
        if (totalRowJsonObj != null && totalRowJsonObj.size() > 0) {
            List<Object> result = new ArrayList<>();
            for (int i = 0; i < getHeadPropList().size(); i++) {
                String item = getHeadPropList().get(i);
                Object dData = totalRowJsonObj.get(item);
                if (i == 1) {
                    result.add("合计");
                } else {
                    result.add(dData);
                }
            }
            return result;
        } else {
            return new ArrayList<>();
        }
    }

    /**
     * 获取表格注释
     *
     * @return Object[]
     */
    private Object[] getRemarks() {
        List<TableRemarkModel> remarks = this.tableModel.getTableRemarks();
        List<String> result = new ArrayList<>();
        if (remarks.size() > 0) {
            for (TableRemarkModel item : remarks) {
                result.add(item.getTitle());
            }
        }
        return result.toArray();
    }

    /**
     * 获取表格主体数据
     *
     * @param twoTuple
     * @return List<List < Object>>
     */
    private List<List<Object>> getBodyData(TwoTuple twoTuple) {
        //添加主体数据
        List<List<Object>> result = new ArrayList<>();
        try {
            for (int i = 0; i < twoTuple.tableData.size(); i++) {
                JSONObject objs = twoTuple.tableData.getJSONObject(i);
                List<Object> objects = new ArrayList<>();
                //这一句添加序号
                //objects.add(i + 1);
                for (String prop : getHeadPropList()) {
                    if (SORT_CODE.equals(prop)) {
                        objects.add(i + 1);
                    } else {
                        objects.add(objs.get(prop));
                    }
                }
                result.add(objects);
            }
        } catch (Exception ex) {
            System.out.print(ex);
        }
        //添加合计行数据
        List<Object> total = getTotal(twoTuple.totalRowJsonObj);
        if (total.size() > 0) {
            result.add(total);
        }
        return result;
    }

    /**
     * 获取表格列
     *
     * @return List<String>
     */
    private List<String> getHeadPropList() {
        List<String> result = new ArrayList<>();
        //添加序号
        result.add(SORT_CODE);
        for (ElementPlusTableColumnModel item : this.tableModel.getCols()) {
            if (item != null) {
                if (item.getChildren() != null) {
                    for (ElementPlusTableColumnModel child : item.getChildren()) {
                        result.add(child.getProp());
                    }
                } else {
                    result.add(item.getProp());
                }
            }
        }
        return result;
    }

    /**
     * 将表格数据转换成指定格式
     *
     * @return TwoTuple
     */
    public static TwoTuple convertTableData(String data) {
        JSONObject jsonResult = JSONObject.parseObject(data);
        String list = jsonResult.getString("data");
        JSONArray tableData = new JSONArray();
        JSONObject totalRowJsonObj = new JSONObject();
        if ("{".equals(list.substring(1, 2))) {
            tableData = JSONObject.parseArray(list);
            totalRowJsonObj = JSONObject.parseObject(jsonResult.getString("totalRow"));
        } else {
            JSONObject objList = JSONObject.parseObject(list);
            tableData = JSONObject.parseArray(objList.getString("list"));
        }
        return new TwoTuple(tableData, totalRowJsonObj);
    }
}
